﻿/*
============================================================================
文件名    ： AccountDB.cs
完全限定名： SSS.DAL.AccountDB
作者      ： 陈存腾
创建时间  ： 2012-03-12
修改时间  ： 
版本      ：
说明      ： 数据库辅助类－账户相关
============================================================================
*/

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
using SSS.Common;

namespace SSS.DAL
{
    /// <summary>
    /// 处理对数据库中用户账户信息的访问
    /// </summary>
    public class AccountDB
    {
        #region 用户ID检查

        /// <summary>
        /// 检测用户ID，并返回用户编号
        /// </summary>
        /// <param name="ID">ID</param>
        /// <returns>用户编号，如果帐号不存在则返回0</returns>
        public static int CheckID(string ID)
        {
            #region 存储过程源码

            //////////////////////////////////////////////////////////////////////////////
            //验证帐号是否存在，若存在则返回用户编号，否则返回0
            //存储过程为：
            //CREATE DEFINER=`root`@`localhost` PROCEDURE `check_user_id`(IN `p_user_id` varchar(255),OUT `p_user_no` int(11))
            //    COMMENT '验证帐号是否存在，若存在则返回用户编号，否则返回0'
            //BEGIN
            //    SET p_user_no = 0;
            //    SELECT `users`.user_no INTO p_user_no FROM `users` WHERE `users`.user_id = p_user_id;
            //END
            //////////////////////////////////////////////////////////////////////////////

            #endregion

            try
            {
                // 指定需要调用的存储过程
                DBProvider.MyCommand.CommandText = "check_user_id";
                // 设置存储过程参数
                DBProvider.Parameters["p_user_id", MySqlDbType.VarChar, 255] = ID;
                DBProvider.Parameters["p_user_no", MySqlDbType.Int32, 11, ParameterDirection.Output] = 0;
                // 打开连接
                DBProvider.Open();
                // 执行存储过程并返回结果
                DBProvider.ExecuteNonQuery();

                return (int)DBProvider.Parameters["p_user_no"];
            }
            catch
            {
                return 0;
            }
            finally
            {
                // 关闭数据库连接
                DBProvider.Close();
            }
        }

        #endregion

        #region 用户注册

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="ID">ID</param>
        /// <param name="Pwd">密码</param>
        /// <param name="IP">客户机IP地址</param>
        /// <returns>是否成功</returns>
        public static bool RegisterHelper(string ID, string Pwd, string IP)
        {
            #region 存储过程源码

            //////////////////////////////////////////////////////////////////////////////
            //用户注册
            //存储过程为：
            //CREATE DEFINER=`root`@`localhost` PROCEDURE `register`(IN `p_user_id` varchar(255),IN `p_user_pwd` varchar(255),IN `p_ip` varchar(255),OUT `p_result` varchar(255))
            //    COMMENT '用户注册'
            //BEGIN
            //    DECLARE purview_accept INT;
            //    SET p_result = "ERROR";
            //    # 验证帐号是否存在
            //    CALL check_user_id(p_user_id, @p_user_no);
            //    IF (@p_user_no) THEN
            //        SET p_result = "帐号已存在";
            //        # 记入日志
            //        CALL log_write(p_user_id, p_ip, "user_add", CONCAT("客户机【",p_ip,"】尝试注册帐号：",p_user_id,"，帐号已存在。"));
            //    ELSE
            //        # 以最后添加的点为道路起始点，存储道路信息到buiding表
            //        INSERT INTO `users`(user_id, user_pwd) VALUES(p_user_id, p_user_pwd);
            //        CALL log_write(p_user_id, p_ip, "user_add", CONCAT("客户机【",p_ip,"】注册帐号：",p_user_id,"，成功。"));
            //        SET p_result = "ACCEPT";
            //    END IF;
            //END
            //////////////////////////////////////////////////////////////////////////////

            #endregion

            try
            {
                // 指定需要调用的存储过程
                DBProvider.MyCommand.CommandText = "register";
                // 设置存储过程参数
                DBProvider.Parameters["p_user_id", MySqlDbType.VarChar, 255] = ID;
                // 客户端已对密码加密，所以这里不需要再次加密
                DBProvider.Parameters["p_user_pwd", MySqlDbType.VarChar, 255] = Pwd;
                DBProvider.Parameters["p_ip", MySqlDbType.VarChar, 255] = IP;
                DBProvider.Parameters["p_result", MySqlDbType.VarChar, 255, ParameterDirection.Output] = 0;
                // 打开连接
                DBProvider.Open();
                // 执行存储过程并返回结果
                DBProvider.ExecuteNonQuery();

                // 判断登录结果
                switch ((string)DBProvider.Parameters["p_result"])
                {
                    case "ACCEPT":
                        return true;
                    default:
                        return false;
                }
            }
            catch
            {
                return false;
            }
            finally
            {
                // 关闭数据库连接
                DBProvider.Close();
            }
        }

        #endregion

        #region 用户登陆

        /// <summary>
        /// 用户登录验证并返回用户信息
        /// </summary>
        /// <param name="ID">ID</param>
        /// <param name="Pwd">帐号密码</param>
        /// <param name="IP">客户机IP地址</param>
        /// <param name="dataTable">用户帐号信息</param>
        /// <returns>操作结果信息</returns>
        public static EnumType.ResultState LoginHelper(string ID, string Pwd, string IP, out DataTable dataTable)
        {
            #region 存储过程

            //////////////////////////////////////////////////////////////////////////////
            //用户登录
            //存储过程为：sp_login
            //参数：
            //      IN `p_user_id` varchar(255)     -- 用户id
            //      IN `p_user_pwd` varchar(255)    -- 用户密码
            //      IN `p_ip` varchar(255)          -- 用户ip
            //结果集：user_id, user_email, user_role, last_login_ip, last_login_time
            //////////////////////////////////////////////////////////////////////////////

            #endregion

            try
            {
                // 设置存储过程参数
                DBProvider.Parameters["p_user_id", MySqlDbType.VarChar, 255] = ID;
                DBProvider.Parameters["p_user_pwd", MySqlDbType.VarChar, 255] = Pwd; // 已加密
                DBProvider.Parameters["p_ip", MySqlDbType.VarChar, 255] = IP;
                // 打开连接
                DBProvider.Open();
                // 执行存储过程并返回结果
                dataTable = DBProvider.ExecuteReader("sp_login");
                // 判断登录结果
                if (0 == dataTable.Rows.Count)
                {
                    return EnumType.ResultState.密码错误或该用户不存在;
                }
                return EnumType.ResultState.成功;
            }
            catch
            {
                dataTable = null;
                return EnumType.ResultState.未知错误;
            }
            finally
            {
                // 关闭数据库连接
                DBProvider.Close();
            }
        }

        #endregion

        #region 修改密码
        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="ID">用户ID</param>
        /// <param name="Pwd">用户密码</param>
        /// <param name="IP">用户IP</param>
        /// <returns></returns>
        public static EnumType.ResultState ChangePassword( string ID, string Pwd, string IP, string newPwd)
        {
            #region 存储过程

            //////////////////////////////////////////////////////////////////////////////
            //用户登录
            //存储过程为：sp_login
            //参数：
            //      IN `p_user_id` varchar(255)     -- 用户id
            //      IN `p_user_pwd` varchar(255)    -- 用户密码
            //      IN `p_ip` varchar(255)          -- 用户ip
            //      IN `p_user_pwd_new` varchar(255)-- 新密码
            //      OUT `p_result` varchar(255)     -- 操作结果
            //////////////////////////////////////////////////////////////////////////////

            #endregion

            try
            {
                // 指定需要调用的存储过程:修改密码
                DBProvider.MyCommand.CommandText = "sp_change_pwd";

                // 设置存储过程参数
                DBProvider.Parameters[ "p_user_id", MySqlDbType.VarChar, 255 ] = ID;
                // 客户端已对密码加密，所以这里不需要再次加密
                DBProvider.Parameters[ "p_user_pwd", MySqlDbType.VarChar, 255 ] = Pwd;
                DBProvider.Parameters[ "p_ip", MySqlDbType.VarChar, 255 ] = IP;
                DBProvider.Parameters[ "p_user_pwd_new", MySqlDbType.VarChar, 255] = newPwd;
                DBProvider.Parameters[ "p_result", MySqlDbType.VarChar, 255, ParameterDirection.Output ] = 0;

                // 打开连接
                DBProvider.Open();
                // 执行存储过程并返回结果
                DBProvider.ExecuteNonQuery();

                // 判断登录结果
                switch ( (string)DBProvider.Parameters[ "p_result" ] )
                {
                    case "成功":
                        return EnumType.ResultState.成功;
                    default:
                        return EnumType.ResultState.未知错误;
                }
            }
            catch
            {
                return EnumType.ResultState.未知错误;
            }
            finally
            {
                // 关闭数据库连接
                DBProvider.Close();
            }
        }
        #endregion

        #region 获取/更新用户信息

        /// <summary>
        /// 提取用户信息
        /// </summary>
        /// <param name="ID">ID</param>
        /// <param name="fID">目标ID</param>
        /// <param name="dataTable">用户信息</param>
        /// <returns>操作结果信息</returns>
        public static EnumType.ResultState UserinfoGetHelper(string ID, string fID, out DataTable dataTable)
        {
            #region 存储过程源码

            //////////////////////////////////////////////////////////////////////////////
            //获取用户信息
            //存储过程为：
            //////////////////////////////////////////////////////////////////////////////

            #endregion

            try
            {
                // 指定需要调用的存储过程
                DBProvider.MyCommand.CommandText = "userinfo_get";
                // 设置存储过程参数
                DBProvider.Parameters["p_user_id", MySqlDbType.VarChar, 255] = ID;
                DBProvider.Parameters["p_friend_id", MySqlDbType.VarChar, 255] = fID;
                DBProvider.Parameters["p_result", MySqlDbType.VarChar, 255, ParameterDirection.Output] = 0;
                // 打开连接
                DBProvider.Open();
                // 执行存储过程并返回结果
                dataTable = DBProvider.ExecuteReader();
                // 判断登录结果
                switch ((string)DBProvider.Parameters["p_result"])
                {
                    case "ACCEPT":
                        return EnumType.ResultState.成功;
                    case "目标账户不存在":
                        return EnumType.ResultState.目标账户不存在;
                    case "用户权限限制":
                        return EnumType.ResultState.用户权限限制;
                    default:
                        return EnumType.ResultState.未知错误;
                }
            }
            catch
            {
                dataTable = null;
                return EnumType.ResultState.未知错误;
            }
            finally
            {
                // 关闭数据库连接
                DBProvider.Close();
            }
        }

        /// <summary>
        /// 更新用户拓展信息
        /// </summary>
        /// <param name="ID">用户ID</param>
        /// <param name="pwd">用户密码</param>
        /// <param name="info">用户拓展信息
        /// info格式：[信息标签1]:[信息值1],[信息标签2]:[信息值2]……
        /// </param>
        /// <returns>操作是否成功</returns>
        public static bool UserinfoUpdateHelper(string ID, string pwd, string IP, string info)
        {
            #region info 格式
            // info格式：[信息标签1]:[信息值1],[信息标签2]:[信息值2]……
            //     例如：user_name:腾,user_gender:男
            // 标签种类及类型：
            //     user_name VARCHAR(255);
            //     user_gender CHAR(2) DEFAULT ('男');
            //     user_birthday date;
            //     user_qq VARCHAR(255);
            //     user_email VARCHAR(255);
            //     user_province VARCHAR(255);
            //     user_city VARCHAR(255);
            //     user_town VARCHAR(255);
            // 由于每个信息字段的标签都是一个字符串，为了防止信息与信息标签相同，
            // 所以把信息值中的下划线"_"都用"\_"来代替
            #endregion

            #region 存储过程源码

            //////////////////////////////////////////////////////////////////////////////
            //获取用户信息
            //存储过程为：
            //CREATE DEFINER=`root`@`localhost` PROCEDURE `user_info_update`(IN `p_user_id` varchar(255),IN `p_user_pwd` varchar(255),IN `p_ip` varchar(255),IN `p_info` text,OUT `p_result` varchar(255))
            //    COMMENT '更新用户扩展信息（由一个info字符串）'
            //BEGIN
            //    DECLARE temp INT DEFAULT (0);
            //    # i用于存放信息字段的标签的坐标;
            //    DECLARE i INT;
            //    # j用于存放信息字段的分隔符','的坐标;
            //    DECLARE j INT DEFAULT (1);
            //    # 用户扩展信息
            //    DECLARE t_user_name VARCHAR(255);
            //    DECLARE t_user_gender CHAR(2) DEFAULT ('男');
            //    DECLARE t_user_birthday date;
            //    DECLARE t_user_qq VARCHAR(255);
            //    DECLARE t_user_email VARCHAR(255);
            //    DECLARE t_user_province VARCHAR(255);
            //    DECLARE t_user_city VARCHAR(255);
            //    DECLARE t_user_town VARCHAR(255);

            //    # 去除info前后空格及在末尾补上‘,’
            //    SET p_info = LTRIM(RTRIM(p_info));
            //    IF (STRCMP(RIGHT(p_info,1), ",") <> 0) THEN
            //        SET p_info = CONCAT(p_info, ",");
            //    END IF;

            //    # 验证用户帐号密码
            //    CALL check_account(p_user_id, p_user_pwd, @result);
            //    SET p_result = @result;
            //    IF (STRCMP(p_result,"ACCEPT")) THEN
            //        # 帐号验证失败
            //        CALL log_write(p_user_id, p_ip, "user_info_update", CONCAT("客户机【", p_ip, "】尝试更新帐号【", p_user_id, "】拓展信息，失败，", p_result, "。"));
            //    ELSE
            //        # 从info中提取用户拓展信息
            //        # 由于每个信息字段的标签都是一个字符串，为了防止信息与信息标签相同，
            //    # 所以把信息值中的下划线"_"都用"\_"来代替
            //        # 因此提取信息时需要用REPLACE(str, '\\_', '_')函数将信息还原
		
            //        # 提取user_name信息
            //        SET i = INSTR(p_info, "user_name:");
            //        SET j = INSTR(p_info, ",");
            //        IF (i && j) THEN
            //            SET i = i + LENGTH("user_name:");
            //            SET t_user_name = REPLACE(SUBSTRING(p_info, i, j - i), '\\_', '_');
            //            SET p_info = SUBSTRING(p_info, j+1);
            //        END IF;
		
            //        # 提取user_gender信息
            //        SET i = INSTR(p_info, "user_gender:");
            //        SET j = INSTR(p_info, ",");
            //        IF (i && j) THEN
            //            SET i = i + LENGTH("user_gender:");
            //            SET t_user_gender = REPLACE(SUBSTRING(p_info, i, j - i), '\\_', '_');
            //            SET p_info = SUBSTRING(p_info, j+1);
            //        END IF;
		
            //        # 提取user_birthday信息
            //        SET i = INSTR(p_info, "user_birthday:");
            //        SET j = INSTR(p_info, ",");
            //        IF (i && j) THEN
            //            SET i = i + LENGTH("user_birthday:");
            //            SET t_user_birthday = REPLACE(SUBSTRING(p_info, i, j - i), '\\_', '_');
            //            SET p_info = SUBSTRING(p_info, j+1);
            //        END IF;
		
            //        # 提取user_qq信息
            //        SET i = INSTR(p_info, "user_qq:");
            //        SET j = INSTR(p_info, ",");
            //        IF (i && j) THEN
            //            SET i = i + LENGTH("user_qq:");
            //            SET t_user_qq = REPLACE(SUBSTRING(p_info, i, j - i), '\\_', '_');
            //            SET p_info = SUBSTRING(p_info, j+1);
            //        END IF;
		
            //        # 提取user_email信息
            //        SET i = INSTR(p_info, "user_email:");
            //        SET j = INSTR(p_info, ",");
            //        IF (i && j) THEN
            //            SET i = i + LENGTH("user_email:");
            //            SET t_user_email = REPLACE(SUBSTRING(p_info, i, j - i), '\\_', '_');
            //            SET p_info = SUBSTRING(p_info, j+1);
            //        END IF;
		
            //        # 提取user_province信息
            //        SET i = INSTR(p_info, "user_province:");
            //        SET j = INSTR(p_info, ",");
            //        IF (i && j) THEN
            //            SET i = i + LENGTH("user_province:");
            //            SET t_user_province = REPLACE(SUBSTRING(p_info, i, j - i), '\\_', '_');
            //            SET p_info = SUBSTRING(p_info, j+1);
            //        END IF;
		
            //        # 提取user_city信息
            //        SET i = INSTR(p_info, "user_city:");
            //        SET j = INSTR(p_info, ",");
            //        IF (i && j) THEN
            //            SET i = i + LENGTH("user_city:");
            //            SET t_user_city = REPLACE(SUBSTRING(p_info, i, j - i), '\\_', '_');
            //            SET p_info = SUBSTRING(p_info, j+1);
            //        END IF;
		
            //        # 提取user_town信息
            //        SET i = INSTR(p_info, "user_town:");
            //        SET j = INSTR(p_info, ",");
            //        IF (i && j) THEN
            //            SET i = i + LENGTH("user_town:");
            //            SET t_user_town = REPLACE(SUBSTRING(p_info, i, j - i), '\\_', '_');
            //            #SET p_info = SUBSTRING(p_info, j+1);
            //        END IF;

            //        # 判断用户信息是否存在
            //        CALL check_user_id(p_user_id, @t_user_no);
            //        SELECT 1 INTO temp FROM userinfo WHERE user_no = @t_user_no;
            //        IF (temp) THEN
            //            UPDATE userinfo SET user_name = t_user_name, user_gender = t_user_gender,
            //                user_birthday = t_user_birthday, user_qq = t_user_qq, user_email = t_user_email,
            //                user_province = t_user_province, user_city = t_user_city, user_town = t_user_town
            //                WHERE user_no = @t_user_no;
            //        ELSE
            //            INSERT INTO userinfo(user_no, user_name, user_gender, user_birthday, user_qq, user_email, user_province, user_city, user_town)
            //                VALUES(@t_user_no, t_user_name, t_user_gender, t_user_birthday, t_user_qq, t_user_email, t_user_province, t_user_city, t_user_town);
            //        END IF;
            //        CALL log_write(p_user_id, p_ip, "user_login", CONCAT("客户机【", p_ip, "】更新帐号【", p_user_id, "】拓展信息，成功。"));
            //    END IF;
            //END
            //////////////////////////////////////////////////////////////////////////////

            #endregion

            try
            {
                // 设置存储过程参数
                DBProvider.Parameters["p_user_id", MySqlDbType.VarChar, 255] = ID;
                DBProvider.Parameters["p_user_pwd", MySqlDbType.VarChar, 255] = pwd;
                DBProvider.Parameters["p_ip", MySqlDbType.VarChar, 255] = IP;
                DBProvider.Parameters["p_info", MySqlDbType.Text] = info;
                DBProvider.Parameters["p_result", MySqlDbType.VarChar, 255, ParameterDirection.Output] = 0;
                // 打开连接并执行命令
                DBProvider.Open();
                DBProvider.ExecuteNonQuery("user_info_update");
                // 返回执行结果
                return ("ACCEPT".Equals(DBProvider.Parameters["p_result"]));
            }
            catch
            {
                return false;
            }
            finally
            {
                // 关闭数据库连接
                DBProvider.Close();
            }
        }

        #endregion

    }
}
